#include "PlaneGeometry.h"

POCELAIN_NAMESPACE_BEGIN

PlaneGeometry::PlaneGeometry(Real width,Real height,size_t widthSegments,size_t heightSegments)
{

    const auto width_half = width / 2;
    const auto height_half = height / 2;

    const auto gridX = std::floor( widthSegments );
    const auto gridY = std::floor( heightSegments );

    const auto gridX1 = gridX + 1;
    const auto gridY1 = gridY + 1;

    const auto segment_width = width / gridX;
    const auto segment_height = height / gridY;

    //

    BufferGeometry::index_array_t::array_t indices;
    Float32BufferAttribute::array_t vertices;
    Float32BufferAttribute::array_t normals;
    Float32BufferAttribute::array_t uvs;

    for ( size_t iy = 0; iy < gridY1; iy ++ )
    {

        const auto y = iy * segment_height - height_half;

        for ( size_t ix = 0; ix < gridX1; ++ix )
        {
            const auto x = ix * segment_width - width_half;

            vertices.push_back( x);
            vertices.push_back( -y);
            vertices.push_back( 0);

            normals.push_back( 0 );
            normals.push_back( 0 );
            normals.push_back( 1 );

            uvs.push_back( ix / gridX );
            uvs.push_back( 1 - ( iy / gridY ) );

        }
    }

    for ( size_t iy = 0; iy < gridY; ++iy )
    {

        for ( size_t ix = 0; ix < gridX; ++ix )
        {

            const auto a = ix + gridX1 * iy;
            const auto b = ix + gridX1 * ( iy + 1 );
            const auto c = ( ix + 1 ) + gridX1 * ( iy + 1 );
            const auto d = ( ix + 1 ) + gridX1 * iy;

            indices.push_back( a );
            indices.push_back( b );
            indices.push_back( d );

            indices.push_back( b );
            indices.push_back( c );
            indices.push_back( d );

        }

    }

    auto indicesAtt = new index_array_t(indices,1);
    auto verticesAtt = new Float32BufferAttribute( vertices, 3 );
    auto normalsAtt = new Float32BufferAttribute( normals, 3 );
    auto uvsAtt = new Float32BufferAttribute( uvs, 2 );

    this->setIndices( indicesAtt );
    this->setAttribute( "position", verticesAtt );
    this->setAttribute( "normal", normalsAtt );
    this->setAttribute( "uv", uvsAtt);

    indicesAtt->release();
    verticesAtt->release();
    normalsAtt->release();
    uvsAtt->release();

}
POCELAIN_NAMESPACE_END
